/*****3d cudex****/
#define PI 3.1415
#define PI_DIV_180 (0.017453292519943296)//π/180
#define DegToRad(x) ((x)*PI_DIV_180)//角度转换为弧度

/*****旋转****/
float cube[8][3] = {{-15, -15, -15}, {-15, 15, -15}, {15, 15, -15}, {15, -15, -15}, {-15, -15, 15}, {-15, 15, 15}, {15, 15, 15}, {15, -15, 15}}; //立方体各点坐标
int lineid[] = {1, 2, 2, 3, 3, 4, 4, 1, 5, 6, 6, 7, 7, 8, 8, 5, 8, 4, 7, 3, 6, 2, 5, 1}; //记录点之间连接顺序

float* matconv(float* a, float b[3][3]) //计算矩阵乘法
{
    float res[3];
    for(int i = 0; i < 3; i++)
        res[i] = b[i][0] * a[0] + b[i][1] * a[1] + b[i][2] * a[2];
    for(int i = 0; i < 3; i++)a[i] = res[i];
    return a;
}

void rotate(float* obj, float x, float y, float z) //旋转该向量
{
    x /= PI;
    y /= PI;
    z /= PI;
    float rz[3][3] = {{cos(z), -sin(z), 0}, {sin(z), cos(z), 0}, {0, 0, 1}};
    float ry[3][3] = {{1, 0, 0}, {0, cos(y), -sin(y)}, {0, sin(y), cos(y)}};
    float rx[3][3] = {{cos(x), 0, sin(x)}, {0, 1, 0}, {-sin(x), 0, cos(x)}};
    matconv(matconv(matconv(obj, rz), ry), rx);
}

/*****放大缩小****/
int points[8][2]; // eight 2D points for the cube, values will be calculated in the code

int orig_points [8][3] =    // eight 3D points - set values for 3D cube
{
    {-1, -1, 1},
    {1, -1, 1},
    {1, 1, 1},
    {-1, 1, 1},
    {-1, -1, -1},
    {1, -1, -1},
    {1, 1, -1},
    {-1, 1, -1}
};

float rotated_3d_points [8][3];   // eight 3D points - rotated around Y axis
float angle_deg = 60.0;           // rotation around the Y axis
float z_offset = -4.0;            // offset on Z axis
float cube_size = 70.0;           // cube size (multiplier)
float time_frame;                 // ever increasing time value

//放大缩小
void cudex_mode_1()
{
    time_frame++;                                // increase the time frame value by 1
    cube_size = 50 + sin(time_frame * 0.2) * 20; // oscilate cube size between values 30 - 70

    //z_offset =  -2.0;    //
    //cube_size = 18.0;    // uncomment those two lines for a "wide angle camera" -- bigger perspective distort

    // increase the angle by 5° increments
    if(angle_deg < 90 - 5)
    {
        angle_deg = angle_deg + 5;
    }
    else
    {
        angle_deg = 0;
    }

    // calculate the points
    for(int i = 0; i < 8; i++)
    {
        // rotate 3d points around the Y axis (rotating X nad Z positions)
        rotated_3d_points [i][0] = orig_points [i][0] * cos(DegToRad(angle_deg)) - orig_points [i][2] * sin(DegToRad(angle_deg));
        rotated_3d_points [i][1] = orig_points [i][1];
        rotated_3d_points [i][2] = orig_points [i][0] * sin(DegToRad(angle_deg)) + orig_points [i][2] * cos(DegToRad(angle_deg)) + z_offset;

        // project 3d points into 2d space with perspective divide -- 2D x = x/z,   2D y = y/z
        points[i][0] = round(64 + rotated_3d_points [i][0] / rotated_3d_points [i][2] * cube_size);
        points[i][1] = round(32 + rotated_3d_points [i][1] / rotated_3d_points [i][2] * cube_size);
    }
    // connect the lines between the individual points
    u8g2_DrawLine(&u8g2,points[ 0 ][ 0 ]+20, points[ 0 ][ 1 ], points[ 1 ][ 0 ]+20, points[ 1 ][ 1 ]);     // connect points 0-1
    u8g2_DrawLine(&u8g2,points[ 1 ][ 0 ]+20, points[ 1 ][ 1 ], points[ 2 ][ 0 ]+20, points[ 2 ][ 1 ]);     // connect points 1-2
    u8g2_DrawLine(&u8g2,points[ 2 ][ 0 ]+20, points[ 2 ][ 1 ], points[ 3 ][ 0 ]+20, points[ 3 ][ 1 ]);     // connect points 2-3
    u8g2_DrawLine(&u8g2,points[ 3 ][ 0 ]+20, points[ 3 ][ 1 ], points[ 0 ][ 0 ]+20, points[ 0 ][ 1 ]);     // connect points 3-0

    u8g2_DrawLine(&u8g2,points[ 4 ][ 0 ]+20, points[ 4 ][ 1 ], points[ 5 ][ 0 ]+20, points[ 5 ][ 1 ]);     // connect points 4-5
    u8g2_DrawLine(&u8g2,points[ 5 ][ 0 ]+20, points[ 5 ][ 1 ], points[ 6 ][ 0 ]+20, points[ 6 ][ 1 ]);     // connect points 5-6
    u8g2_DrawLine(&u8g2,points[ 6 ][ 0 ]+20, points[ 6 ][ 1 ], points[ 7 ][ 0 ]+20, points[ 7 ][ 1 ]);     // connect points 6-7
    u8g2_DrawLine(&u8g2,points[ 7 ][ 0 ]+20, points[ 7 ][ 1 ], points[ 4 ][ 0 ]+20, points[ 4 ][ 1 ]);     // connect points 7-4

    u8g2_DrawLine(&u8g2,points[ 0 ][ 0 ]+20, points[ 0 ][ 1 ], points[ 4 ][ 0 ]+20, points[ 4 ][ 1 ]);     // connect points 0-4
    u8g2_DrawLine(&u8g2,points[ 1 ][ 0 ]+20, points[ 1 ][ 1 ], points[ 5 ][ 0 ]+20, points[ 5 ][ 1 ]);     // connect points 1-5
    u8g2_DrawLine(&u8g2,points[ 2 ][ 0 ]+20, points[ 2 ][ 1 ], points[ 6 ][ 0 ]+20, points[ 6 ][ 1 ]);     // connect points 2-6
    u8g2_DrawLine(&u8g2,points[ 3 ][ 0 ]+20, points[ 3 ][ 1 ], points[ 7 ][ 0 ]+20, points[ 7 ][ 1 ]);     // connect points 3-7
}

//旋转
void cudex_mode_2(){
    for(int i = 0; i < 8; i++)
    {
        rotate(cube[i], 0.5f, 0.3f, 0);   //旋转每个点
    }
    for(int i = 0; i < 24; i += 2) //绘制立方体
    {
        u8g2_DrawLine(&u8g2, 64 + cube[lineid[i] - 1][0]-30, 32 + cube[lineid[i] - 1][1], 64 + cube[lineid[i + 1] - 1][0]-30, 32 + cube[lineid[i + 1] - 1][1]);
    }
}
